const Event = function() {
    this.__listeners = {}
    this.__curUsedId = 0
}

/**
 * 注册侦听事件
 * @param {string} evt 事件名称
 * @param {function} cb 触发回调函数
 * @returns {number} 事件唯一id
 */
Event.prototype.on = function(evt, cb) {
    return this.___add(evt, cb, false)
}

/**
 * 注册一次侦听事件
 * @param {string} evt 事件名称
 * @param {function} cb 触发回调函数
 * @returns {number} 事件唯一id
 */
Event.prototype.once = function(evt, cb) {
    return this.___add(evt, cb, true)
}

/**
 * 移除侦听事件
 * @param {id} id 
 */
Event.prototype.off = function(id) {
    this.__remove(id)
}

/**
 * 清除对应事件的所有侦听
 * @param {string} evt 事件名称
 */
Event.prototype.clearEvt = function(evt) {
    delete this.__listeners[evt]
}

/**
 * 清空所有侦听事件
 */
Event.prototype.clear = function() {
    this.__listeners = {}
}

/**
 * 触发侦听
 * @param {string} evt 事件名称
 * @param {object} param 事件参数
 */
Event.prototype.fire = function(evt, param) {
    this.__call(evt, param)
}


Event.prototype.___add = function(evt, cb, once) {
    if (typeof evt !== 'string' || typeof cb !=='function') {
        return -1
    }

    this.__curUsedId += 1

    var listener = {
        id: this.__curUsedId, 
        cb: cb, 
        once: once
    }

    if (!Array.isArray(this.__listeners[evt])) {
        this.__listeners[evt] = []
    }

    this.__listeners[evt].push(listener)

    return listener.id
}

Event.prototype.__remove = function(id) {
    for (var evt in this.__listeners) {
        var arr = this.__listeners[evt]
        for (var i in arr) {
            var listener = arr[i]
            if (listener.id == id) {
                arr.splice(i, 1)
                return
            }
        }
    }
}

Event.prototype.__call = function(evt, param) {
    if (!this.__listeners) {
        return
    }

    var arr = this.__listeners[evt]
    if (!arr) {
        return
    }

    for (var i = arr.length - 1; i >= 0; --i) {
        var listener = arr[i]
        if (!listener) {
            continue
        }
        
        listener.cb && listener.cb(param)

        if (listener.once) {
            arr.splice(i, 1)
        }
    }
}

module.exports = Event